home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / asxsrc.arc / Z80MCH.C < prev    next >
C/C++ Source or Header  |  1989-08-25  |  9KB  |  598 lines

  1. /* z80mch.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <setjmp.h>
  14. #include "asm.h"
  15. #include "z80.h"
  16.  
  17. char    imtab[3] = { 0x46, 0x56, 0x5E };
  18. int    hd64;
  19.  
  20. /*
  21.  * Process a machine op.
  22.  */
  23. VOID
  24. machine(mp)
  25. struct mne *mp;
  26. {
  27.     register op, t1, t2;
  28.     struct expr e1, e2;
  29.     int rf, v1, v2;
  30.  
  31.     op = mp->m_valu;
  32.     rf = mp->m_type;
  33.     if (!hd64 && rf>X_HD64)
  34.         rf = 0;
  35.     switch (rf) {
  36.  
  37.     case S_INH1:
  38.         outab(op);
  39.         break;
  40.  
  41.     case S_INH2:
  42.         outab(0xED);
  43.         outab(op);
  44.         break;
  45.  
  46.     case S_RET:
  47.         if (more()) {
  48.             if (v1 = admode(CND)) {
  49.                 outab(op | v1<<3);
  50.             } else {
  51.                 qerr();
  52.             }
  53.         } else {
  54.             outab(0xC9);
  55.         }
  56.         break;
  57.  
  58.     case S_PUSH:
  59.         if (admode(R16X)) {
  60.             outab(op+0x30);
  61.             break;
  62.         } else
  63.         if ((v1=admode(R16)) && (v1&=0xFF)!=SP) {
  64.             if (v1 != gixiy(v1)) {
  65.                 outab(op+0x20);
  66.                 break;
  67.             }
  68.             outab(op | v1<<4);
  69.             break;
  70.         }
  71.         aerr();
  72.         break;
  73.  
  74.     case S_RST:
  75.         v1 = absexpr();
  76.         if (v1 & ~0x38) {
  77.             aerr();
  78.             v1 = 0;
  79.         }
  80.         outab(op|v1);
  81.         break;
  82.  
  83.     case S_IM:
  84.         expr(&e1, 0);
  85.         abscheck(&e1);
  86.         if (e1.e_addr > 2) {
  87.             aerr();
  88.             e1.e_addr = 0;
  89.         }
  90.         outab(op);
  91.         outab(imtab[e1.e_addr]);
  92.         break;
  93.  
  94.     case S_BIT:
  95.         expr(&e1, 0);
  96.         t1 = 0;
  97.         v1 = e1.e_addr;
  98.         if (v1 > 7) {
  99.             ++t1;
  100.             v1 &= 0x07;
  101.         }
  102.         op |= (v1<<3);
  103.         comma();
  104.         addr(&e2);
  105.         abscheck(&e1);
  106.         if (genop(0xCB, op, &e2, 0) || t1)
  107.             aerr();
  108.         break;
  109.  
  110.     case S_RL:
  111.         t1 = 0;
  112.         t2 = addr(&e2);
  113.         if (more()) {
  114.             if ((t2 != S_R8) || (e2.e_addr != A))
  115.                 ++t1;
  116.             comma();
  117.             t2 = addr(&e2);
  118.         }
  119.         if (genop(0xCB, op, &e2, 0) || t1)
  120.             aerr();
  121.         break;
  122.  
  123.     case S_AND:
  124.     case S_SUB:
  125.         t1 = 0;
  126.         t2 = addr(&e2);
  127.         if (more()) {
  128.             if ((t2 != S_R8) || (e2.e_addr != A))
  129.                 ++t1;
  130.             comma();
  131.             t2 = addr(&e2);
  132.         }
  133.         if (rf==S_SUB && t2!=S_IMMED) {
  134.             if (genop(0xCB, op, &e2, 0) || t1)
  135.                 aerr();
  136.         } else {
  137.             if (genop(0, op, &e2, 1) || t1)
  138.                 aerr();
  139.         }
  140.         break;
  141.  
  142.     case S_ADD:
  143.     case S_ADC:
  144.     case S_SBC:
  145.         t1 = addr(&e1);
  146.         t2 = 0;
  147.         if (more()) {
  148.             comma();
  149.             t2 = addr(&e2);
  150.         }
  151.         if (t2 == 0) {
  152.             if (genop(0, op, &e1, 1))
  153.                 aerr();
  154.             break;
  155.         }
  156.         if ((t1 == S_R8) && (e1.e_addr == A)) {
  157.             if (genop(0, op, &e2, 1))
  158.                 aerr();
  159.             break;
  160.         }
  161.         if ((t1 == S_R16) && (t2 == S_R16)) {
  162.             if (rf == S_ADD)
  163.                 op = 0x09;
  164.             if (rf == S_ADC)
  165.                 op = 0x4A;
  166.             if (rf == S_SBC)
  167.                 op = 0x42;
  168.             v1 = e1.e_addr;
  169.             v2 = e2.e_addr;
  170.             if ((v1 == HL) && (v2 <= SP)) {
  171.                 if (rf != S_ADD)
  172.                     outab(0xED);
  173.                 outab(op | (v2<<4));
  174.                 break;
  175.             }
  176.             if (rf != S_ADD) {
  177.                 aerr();
  178.                 break;
  179.             }
  180.             if ((v1 == IX) && (v2 != HL) && (v2 != IY)) {
  181.                 if (v2 == IX)
  182.                     v2 = HL;
  183.                 outab(0xDD);
  184.                 outab(op | (v2<<4));
  185.                 break;
  186.             }
  187.             if ((v1 == IY) && (v2 != HL) && (v2 != IX)) {
  188.                 if (v2 == IY)
  189.                     v2 = HL;
  190.                 outab(0xFD);
  191.                 outab(op | (v2<<4));
  192.                 break;
  193.             }
  194.         }
  195.         aerr();
  196.         break;
  197.  
  198.     case S_LD:
  199.         t1 = addr(&e1);
  200.         comma();
  201.         t2 = addr(&e2);
  202.         if (t1 == S_R8) {
  203.             v1 = op | e1.e_addr<<3;
  204.             if (genop(0, v1, &e2, 0) == 0)
  205.                 break;
  206.             if (t2 == S_IMMED) {
  207.                 outab(e1.e_addr<<3 | 0x06);
  208.                 outrb(&e2,0);
  209.                 break;
  210.             }
  211.         }
  212.         v1 = e1.e_addr;
  213.         v2 = e2.e_addr;
  214.         if ((t1 == S_R16) && (t2 == S_IMMED)) {
  215.             v1 = gixiy(v1);
  216.             outab(0x01|v1<<4);
  217.             outrw(&e2, 0);
  218.             break;
  219.         }
  220.         if ((t1 == S_R16) && (t2 == S_INDM)) {
  221.             if (gixiy(v1) == HL) {
  222.                 outab(0x2A);
  223.             } else {
  224.                 outab(0xED);
  225.                 outab(0x4B | v1<<4);
  226.             }
  227.             outrw(&e2, 0);
  228.             break;
  229.         }
  230.         if ((t1 == S_INDM) && (t2 == S_R16)) {
  231.             if (gixiy(v2) == HL) {
  232.                 outab(0x22);
  233.             } else {
  234.                 outab(0xED);
  235.                 outab(0x43 | v2<<4);
  236.             }
  237.             outrw(&e1, 0);
  238.             break;
  239.         }
  240.         if ((t1 == S_R8) && (v1 == A) && (t2 == S_INDM)) {
  241.             outab(0x3A);
  242.             outrw(&e2, 0);
  243.             break;
  244.         }
  245.         if ((t1 == S_INDM) && (t2 == S_R8) && (v2 == A)) {
  246.             outab(0x32);
  247.             outrw(&e1, 0);
  248.             break;
  249.         }
  250.         if ((t2 == S_R8) && (gixiy(t1) == S_IDHL)) {
  251.             outab(0x70|v2);
  252.             if (t1 != S_IDHL)
  253.                 outrb(&e1, 0);
  254.             break;
  255.         }
  256.         if ((t2 == S_IMMED) && (gixiy(t1) == S_IDHL)) {
  257.             outab(0x36);
  258.             if (t1 != S_IDHL)
  259.                 outrb(&e1, 0);
  260.             outrb(&e2, 0);
  261.             break;
  262.         }
  263.         if ((t1 == S_R8X) && (t2 == S_R8) && (v2 == A)) {
  264.             outab(0xED);
  265.             outab(v1);
  266.             break;
  267.         }
  268.         if ((t1 == S_R8) && (v1 == A) && (t2 == S_R8X)) {
  269.             outab(0xED);
  270.             outab(v2|0x10);
  271.             break;
  272.         }
  273.         if ((t1 == S_R16) && (v1 == SP)) {
  274.             if ((t2 == S_R16) && (gixiy(v2) == HL)) {
  275.                 outab(0xF9);
  276.                 break;
  277.             }
  278.         }
  279.         if ((t1 == S_R8) && (v1 == A)) {
  280.             if ((t2 == S_IDBC) || (t2 == S_IDDE)) {
  281.                 outab(0x0A | (t2-S_INDR)<<4);
  282.                 break;
  283.             }
  284.         }
  285.         if ((t2 == S_R8) && (v2 == A)) {
  286.             if ((t1 == S_IDBC) || (t1 == S_IDDE)) {
  287.                 outab(0x02 | (t1-S_INDR)<<4);
  288.                 break;
  289.             }
  290.         }
  291.         aerr();
  292.         break;
  293.  
  294.  
  295.     case S_EX:
  296.         t1 = addr(&e1);
  297.         comma();
  298.         t2 = addr(&e2);
  299.         if (t2 == S_R16) {
  300.             v1 = e1.e_addr;
  301.             v2 = e2.e_addr;
  302.             if ((t1 == S_IDSP) && (v1 == 0)) {
  303.                 if (gixiy(v2) == HL) {
  304.                     outab(op);
  305.                     break;
  306.                 }
  307.             }
  308.             if (t1 == S_R16) {
  309.                 if ((v1 == DE) && (v2 == HL)) {
  310.                     outab(0xEB);
  311.                     break;
  312.                 }
  313.             }
  314.         }
  315.         if ((t1 == S_R16X) && (t2 == S_R16X)) {
  316.             outab(0x08);
  317.             break;
  318.         }
  319.         aerr();
  320.         break;
  321.  
  322.     case S_IN:
  323.     case S_OUT:
  324.         if (rf == S_IN) {
  325.             t1 = addr(&e1);
  326.             comma();
  327.             t2 = addr(&e2);
  328.         } else {
  329.             t2 = addr(&e2);
  330.             comma();
  331.             t1 = addr(&e1);
  332.         }
  333.         v1 = e1.e_addr;
  334.         v2 = e2.e_addr;
  335.         if (t1 == S_R8) {
  336.             if ((v1 == A) && (t2 == S_INDM)) {
  337.                 outab(op);
  338.                 outab(v2);
  339.                 break;
  340.             }
  341.             if (t2 == S_IDC) {
  342.                 outab(0xED);
  343.                 outab(((rf == S_IN) ? 0x40 : 0x41) + (v1<<3));
  344.                 break;
  345.             }
  346.         }
  347.         aerr();
  348.         break;
  349.  
  350.     case S_DEC:
  351.     case S_INC:
  352.         t1 = addr(&e1);
  353.         v1 = e1.e_addr;
  354.         if (t1 == S_R8) {
  355.             outab(op|(v1<<3));
  356.             break;
  357.         }
  358.         if (t1 == S_IDHL) {
  359.             outab(op|0x30);
  360.             break;
  361.         }
  362.         if (t1 != gixiy(t1)) {
  363.             outab(op|0x30);
  364.             outrb(&e1,0);
  365.             break;
  366.         }
  367.         if (t1 == S_R16) {
  368.             v1 = gixiy(v1);
  369.             if (rf == S_INC) {
  370.                 outab(0x03|(v1<<4));
  371.                 break;
  372.             }
  373.             if (rf == S_DEC) {
  374.                 outab(0x0B|(v1<<4));
  375.                 break;
  376.             }
  377.         }
  378.         aerr();
  379.         break;
  380.  
  381.     case S_DJNZ:
  382.     case S_JR:
  383.         if ((v1=admode(CND)) && (rf != S_DJNZ)) {
  384.             if ((v1&=0xFF) <= 0x18) {
  385.                 op += (v1+1)<<3;
  386.             } else {
  387.                 aerr();
  388.             }
  389.             comma();
  390.         }
  391.         expr(&e2, 0);
  392.         v2 = e2.e_addr - dot->s_addr - 2;
  393.         if ((v2 < -128) || (v2 > 127))
  394.             aerr();
  395.         if (e2.e_base.e_ap != dot->s_area)
  396.             rerr();
  397.         outab(op);
  398.         outab(v2);
  399.         break;
  400.  
  401.     case S_CALL:
  402.         if (v1=admode(CND)) {
  403.             op |= (v1&0xFF)<<3;
  404.             comma();
  405.         } else {
  406.             op = 0xCD;
  407.         }
  408.         expr(&e1, 0);
  409.         outab(op);
  410.         outrw(&e1, 0);
  411.         break;
  412.  
  413.     case S_JP:
  414.         if (v1=admode(CND)) {
  415.             op |= (v1&0xFF)<<3;
  416.             comma();
  417.             expr(&e1, 0);
  418.             outab(op);
  419.             outrw(&e1, 0);
  420.             break;
  421.         }
  422.         t1 = addr(&e1);
  423.         if (t1 == S_USER) {
  424.             outab(0xC3);
  425.             outrw(&e1, 0);
  426.             break;
  427.         }
  428.         if ((e1.e_addr == 0) && (gixiy(t1) == S_IDHL)) {
  429.             outab(0xE9);
  430.             break;
  431.         }
  432.         aerr();
  433.         break;
  434.  
  435.     case X_HD64:
  436.         ++hd64;
  437.         break;
  438.  
  439.     case X_INH2:
  440.         outab(0xED);
  441.         outab(op);
  442.         break;
  443.  
  444.     case X_IN:
  445.     case X_OUT:
  446.         if (rf == X_IN) {
  447.             t1 = addr(&e1);
  448.             comma();
  449.             t2 = addr(&e2);
  450.         } else {
  451.             t2 = addr(&e2);
  452.             comma();
  453.             t1 = addr(&e1);
  454.         }
  455.         if ((t1 == S_R8) && (t2 == S_INDM)) {
  456.             outab(0xED);
  457.             outab(op | e1.e_addr<<3);
  458.             outrb(&e2, 0);
  459.             break;
  460.         }
  461.         aerr();
  462.         break;
  463.  
  464.     case X_MLT:
  465.         t1 = addr(&e1);
  466.         if ((t1 == S_R16) && ((v1 = e1.e_addr) <= SP)) {
  467.             outab(0xED);
  468.             outab(op | v1<<4);
  469.             break;
  470.         }
  471.         aerr();
  472.         break;
  473.  
  474.     case X_TST:
  475.         t1 = addr(&e1);
  476.         if (t1 == S_R8) {
  477.             outab(0xED);
  478.             outab(op | e1.e_addr<<3);
  479.             break;
  480.         }
  481.         if (t1 == S_IDHL) {
  482.             outab(0xED);
  483.             outab(0x34);
  484.             break;
  485.         }
  486.         if (t1 == S_IMMED) {
  487.             outab(0xED);
  488.             outab(0x64);
  489.             outrb(&e1, 0);
  490.             break;
  491.         }
  492.         aerr();
  493.         break;
  494.  
  495.     case X_TSTIO:
  496.         t1 = addr(&e1);
  497.         if (t1 == S_IMMED) {
  498.             outab(0xED);
  499.             outab(op);
  500.